#include "includes.h"

extern struct msg_view_change vc_list;
extern struct msg_prepare *prep;
extern int host_count;	
extern int last_attempted;
extern int last_proposed;
extern int last_installed;
extern int local_aru;
extern int my_id;
extern int state;
extern struct msg_client_update pending_updates;
extern struct msg_client_update update_queue;
extern char* coordinator_hostname;
	
void shift_to_leader_election(int view) {

	state = STATE_LEADER_ELECTION;
	clear_vc_list();
	//Clear Prepare?
	prep = NULL;
	clear_prep_ok_list();
	clear_last_enqueued();
	
	last_attempted = view;
	
	//int new_server = last_attempted % host_count;
	struct msg_view_change* tmp = create_view_change(my_id, last_attempted);
	send_to_all(serialize_view_change(tmp));
	update_data_structures(serialize_view_change(tmp));
}


int preinstall_ready(int view) {
	//Check whether we have floor(N/2) + 1 entries
	struct msg_view_change *tmp;
	struct list_head *pos;
	int count = 0;
	
	if(view <= last_installed) {
		return 0;
	}
	
	list_for_each(pos, &vc_list.list) {
		tmp = list_entry(pos, struct msg_view_change, list);
		if(tmp->attempted == view) {
			count ++;
			if(count >= (host_count/2 + 1)) {
				return 1;
			}
		}	
	}
	
	return 0;
}

void shift_to_reg_leader(){

	DEBUGPRINT("Shifting to REGULAR LEADER\n",NULL);
	state = STATE_REG_LEADER;
	enqueue_unbound_pending_updates();
	remove_bound_updates_from_queue();
	last_proposed = local_aru;
	send_proposal();
	//DEBUGPRINT("STRL DONE\n",NULL);
}

void shift_to_reg_non_leader(){

	DEBUGPRINT("Shifting to REGULAR *NON* LEADER\n",NULL);
	state = STATE_REG_NONLEADER;
	last_installed = last_attempted;
	
	struct msg_client_update *tmp;
	struct list_head *pos;
	
	//DEBUGPRINT("- - - - - -- - - - - - - - - - Sending Old Updates to Leader\n",NULL);
	list_for_each(pos, &pending_updates.list){
		tmp = list_entry(pos, struct msg_client_update, list);
		
		send_to_one(serialize_client_update(tmp),coordinator_hostname,1);
	}
	
	list_for_each(pos, &update_queue.list){
		tmp = list_entry(pos, struct msg_client_update, list);
		send_to_one(serialize_client_update(tmp),coordinator_hostname,1);
	}
	
	clear_update_queue();
	sync();
}


